﻿using MS_Entity;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml;
using System.IO;
using DAL;
using System.Xml.Schema;
using wanzheng.MS_UI;




namespace MS_UI
{
    public partial class FrmIOVarConfig : Form
    {
        public FrmIOVarConfig()
        {

            InitializeComponent();

            this.Load += FrmIOVarConfig_Load;
            this.dgv_data.AutoGenerateColumns = false;

        }


        //Modbus变量List集合
        private List<Variable_Modbus> VarList = new List<Variable_Modbus>();

        //Modbus报警标量list集合

        private List<VarAlarm_Modbus> VarAlarmList = new List<VarAlarm_Modbus>();


        //创建modbus变量路径
        private string VarPath=Application.StartupPath+"\\ConfigFile\\"+"Variable_Modbus.xml";

             //创建报警变量路径
        private string VarAlarmPath = Application.StartupPath + "\\ConfigFile\\"+"VarAlarm_Modbus.xml";

               //创建StoreArea变量路径
        private string StoreAreaPath = Application.StartupPath + "\\ConfigFile\\"+"StoreArea.xml";

        private void btn_New_Click(object sender, EventArgs e)
        {
            Frm_NewVar_Mod objFrm = new Frm_NewVar_Mod();
            //打开窗体
            objFrm.ShowDialog();



            DialogResult dr = objFrm.DialogResult;
            if (dr == DialogResult.OK)
            {
                this.VarList.Add(objFrm.var);
                if (objFrm.varAlarm != null)
                {

                    this.VarAlarmList.Add(objFrm.varAlarm);


                }
            }

            UpdateDGV();
        }

        private void UpdateDGV()
        {
            this.dgv_data.DataSource = null;
            this.dgv_data.DataSource = this.VarList;


        }
        #region 向XML文件中添加节点属性信息

        /// <summary>
        /// 添加节点属性信息
        /// </summary>
        /// <param name="name"></param>
        /// <param name="value"></param>
        /// <param name="head"></param>
        private void XMLAttributeAppend(XmlDocument rootxml, string name, string value, XmlElement head)
        {

            XmlAttribute att = rootxml.CreateAttribute(name);
            att.Value = value;
            head.Attributes.Append(att);



        }

        #endregion

        #region 根据节点及节点名称获取相应的值

        /// <summary>
        /// 根据节点及节点名称获取相应的值
        /// </summary>
        /// <param name="rootxml"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        private string XMLAttributeGetValue(XmlNode rootxml,string name)
        { 
        string resvalue=string.Empty;
            if (rootxml != null && rootxml.Attributes != null && rootxml.Attributes[name] != null)
            {

                resvalue = rootxml.Attributes[name].Value;
            
            
            }

            return resvalue;
        }


        #endregion

        private void btn_Save_Click(object sender, EventArgs e)
        {
            //保存分三步
           
            #region
            //第一步：保存MODBUS变量XML文件
            XmlDocument rootxml = new XmlDocument();
            XmlElement rootnode = rootxml.CreateElement("Root");

            foreach (Variable_Modbus item in this.VarList)
            {

                XmlElement xmle = rootxml.CreateElement("Variable");
                XMLAttributeAppend(rootxml, "VarName", item.VarName, xmle);
                XMLAttributeAppend(rootxml, "Address", item.Address, xmle);
                XMLAttributeAppend(rootxml, "DataType", item.DataType, xmle);
                XMLAttributeAppend(rootxml, "StireArea", item.StoreArea, xmle);
                XMLAttributeAppend(rootxml, "Note", item.Note, xmle);
                XMLAttributeAppend(rootxml, "IsFiling", item.IsFiling, xmle);
                XMLAttributeAppend(rootxml, "IsAlarm", item.IsAlarm, xmle);
                XMLAttributeAppend(rootxml, "IsReport", item.IsReport, xmle);
                XMLAttributeAppend(rootxml, "AbsoluteAddress", item.AbsoluteAddress, xmle);

                rootnode.AppendChild(xmle);

            }

            rootxml.AppendChild(rootnode);

            if (File.Exists(VarPath))
            { 
            
            File.Delete(VarPath);
            
            
            }


            //保存要调用路径
            rootxml.Save(VarPath);


            //第二部保存存储区变量到XML文件

            List<StoreArea> storeList = Calculate();
            XmlDocument rootxml1 = new XmlDocument();
            XmlElement rootnode1 = rootxml1.CreateElement("Root");

            foreach (StoreArea item in storeList)
            {

                XmlElement xmle1 = rootxml1.CreateElement("StoreArea");
                XMLAttributeAppend(rootxml1, "StoreType", item.StoreType, xmle1);
                XMLAttributeAppend(rootxml1, "StartReg", item.StartReg.ToString(), xmle1);
                XMLAttributeAppend(rootxml1, "Length", item.Length.ToString(), xmle1);
             
                rootnode1.AppendChild(xmle1);

            }

            rootxml1.AppendChild(rootnode1);

            if (File.Exists(StoreAreaPath))
            {

                File.Delete(StoreAreaPath);


            }


            //保存要调用路径
            rootxml1.Save(StoreAreaPath);



            //第三部保存报警变量到XML文件

            try { 
            XmlDocument rootxml2 = new XmlDocument();
            XmlElement rootnode2 = rootxml.CreateElement("Root");

            foreach (VarAlarm_Modbus item in this.VarAlarmList)
            {

                XmlElement xmle2 = rootxml2.CreateElement("VarAlarm");
                XMLAttributeAppend(rootxml2, "VarName", item.VarName, xmle2);
              string alarm=string.Empty;
                foreach (Alarm it in item.VarAlarm)
                { 
                alarm=it.AlarmType+";"+it.AlarmVaule.ToString()+";"+it.Priority.ToString()+";"+it.Note+"|";

                
                
                }

                XMLAttributeAppend(rootxml2, "Alarm",alarm, xmle2);
                rootnode2.AppendChild(xmle2);

            }

            rootxml2.AppendChild(rootnode2);

            if (File.Exists(VarAlarmPath))
            {

                File.Delete(VarAlarmPath);


            }


            //保存要调用路径
            rootxml2.Save(VarAlarmPath);
            }
            catch(Exception ex)
            {

                MessageBox.Show("保存出错"+ex.Message,"保存提示");
            
            }

            MessageBox.Show("保存成功");
            UpdateDGV();
            #endregion

        }

        #region 根据当前变量集合进行自动计算，计算出存储区域的集合

        private List<StoreArea> Calculate()
        {

            List<StoreArea> StoreList = new List<StoreArea>();
            List<Variable_Modbus> List_0x = new List<Variable_Modbus>();
            List<Variable_Modbus> List_1x = new List<Variable_Modbus>();
            List<Variable_Modbus> List_2x = new List<Variable_Modbus>();
            List<Variable_Modbus> List_3x = new List<Variable_Modbus>();
            List<Variable_Modbus> List_4x = new List<Variable_Modbus>();

            foreach (Variable_Modbus item in this.VarList)
            {
                if (item.StoreArea == "01 Coil Status(0x)")
                {
                    List_0x.Add(item);
                }
                if (item.StoreArea == "02 Input Status(1x)")
                {
                    List_1x.Add(item);
                }
                if (item.StoreArea == "03 Holding Register(4x)")
                {
                    List_2x.Add(item);
                }
                if (item.StoreArea == "04 Input Registers(3x)")
                {
                    List_3x.Add(item);
                }

            }

            if (List_0x.Count > 0)
            {
                StoreList.Add(new StoreArea()
                {
                    StoreType = "01 Coil Status(0x)",
                    StartReg = AnalyseVar(List_0x)[0],
                    Length = AnalyseVar(List_0x)[1]
                });
            }

            if (List_4x.Count > 0)
            {
                StoreList.Add(new StoreArea()
                {
                    StoreType = "03 Holding Register(4x)",
                    StartReg = AnalyseVar(List_4x)[0],
                    Length= AnalyseVar(List_4x)[1]
                });
            }


            return StoreList;
        }


        //对变量进行分析，返回第一个数值为起始地址，第二个数值为长度

        private List<int> AnalyseVar(List<Variable_Modbus> list)
        { 
        List<int>ResultList = new List<int>(2);
            List<int> AddressList = new List<int>();
            int Start = 0;
            int End = 0;
            int Length = 0;
            string DataType=String.Empty;
            foreach (Variable_Modbus item in list)
            {

                AddressList.Add(int.Parse(item.Address));
            }
           // Start = GetMin(AddressList);
           // End = GetMax(AddressList);

            foreach (Variable_Modbus item in list)
            {
                if (item.Address == End.ToString())
                { 
                DataType = item.DataType;
                
                
                }
            }

            switch (DataType)
            {

                case "Bool":
                    Length = End - Start + 1;
                    break;
                case "Float":
                    Length = End - Start + 2;
                    break;
                case "Float Inverse":
                    Length = End - Start + 2;
                    break;
                case "Long":
                    Length = End - Start + 2;
                    break;
                case "Long Inverse":
                    Length = End - Start + 2;
                    break;
                case "Double":
                    Length = End - Start + 4;
                    break;
                case "Double Inverse":
                    Length = End - Start + 4;
                    break;

                default:
                    Length = End - Start + 2;
                    break;


            }
            ResultList.Add(Start);
            ResultList.Add(Length);
            return ResultList;

        }




        

        private void btn_Modify_Click(object sender, EventArgs e)
        {

            if (this.dgv_data.SelectedRows.Count > 0)
            { 
            
            int index=this.dgv_data.CurrentRow.Index;
            
            Variable_Modbus ModVar=this.VarList[index];
            VarAlarm_Modbus AlarmVar=new VarAlarm_Modbus();

                if (ModVar.IsAlarm == "1")
                { 
                foreach(VarAlarm_Modbus item in this.VarAlarmList)
                    {
                        if (item.VarName == ModVar.VarName)
                        { 
                        AlarmVar = item;
                        
                        }
                        
                    }
                
                }

                Frm_ModVar_Mod objFrm=new Frm_ModVar_Mod(ModVar,AlarmVar);

                DialogResult dr=objFrm.ShowDialog();

                if (dr == DialogResult.OK)
                {
                    this.VarList[index] = objFrm.var;
                VarAlarm_Modbus varAlarm=objFrm.varAlarm;
                    if (varAlarm != null)
                    {
                        //判断报警是新增还是修改
                        if (SelectVarAlarm(varAlarm, VarAlarmList))
                        {
                            //修改
                            this.VarAlarmList.Add(varAlarm);


                        }
                        else
                        {
                            for (int i = 0; i < this.VarAlarmList.Count; i++)
                            {

                                if (this.VarAlarmList[i].VarName == varAlarm.VarName)
                                { 
                                
                                this.VarAlarmList [i] = varAlarm;

                                    break;
                                }
                            
                            }
                        
                        
                        
                        }



                    }
                
                }
                UpdateDGV();

            }

        }

        #endregion



        #region 根据Modbus变量路径返回变量集合

        private List<Variable_Modbus> LoadXML(string xmlpath)
        {

            List<Variable_Modbus> VarModbusList=null;
            if (!File.Exists(xmlpath))
            {

                MessageBox.Show("IO配置文件不存在");
               
            }
            else
            { 
            VarModbusList = new List<Variable_Modbus>();
                XmlDocument xdoc= new XmlDocument();
                xdoc.Load(xmlpath);
                foreach (XmlNode nooderoot in xdoc.ChildNodes)
                {

                    if (nooderoot.Name == "Root")
                    {
                        foreach (XmlNode noodchild in nooderoot.ChildNodes)
                        {
                            if (noodchild.Name== "Variable")
                            { 
                            
                            Variable_Modbus objVar=new Variable_Modbus();
                                objVar.VarName = XMLAttributeGetValue(noodchild,"VarName");
                                objVar.VarName = XMLAttributeGetValue(noodchild, "StoreArea");
                                objVar.VarName = XMLAttributeGetValue(noodchild, "Address");
                                objVar.VarName = XMLAttributeGetValue(noodchild, "DataType");
                                objVar.VarName = XMLAttributeGetValue(noodchild, "IsFiling");
                                objVar.VarName = XMLAttributeGetValue(noodchild, "IsAlarm");
                                objVar.VarName = XMLAttributeGetValue(noodchild, "IsReport");
                                objVar.VarName = XMLAttributeGetValue(noodchild, "AbsoluteAddress");

                                VarModbusList.Add(objVar);
                            }


                        }
                    
                    }
                
                }

               
            }
         return VarModbusList;
        }

        #endregion


        #region 根据XMLAlarm文件返回报警变量集合
        private List<VarAlarm_Modbus> LoadAlarmXML(string xmlpath)
        {

            List<VarAlarm_Modbus> VarAlarmList = null;
            if (!File.Exists(xmlpath))
            {

                MessageBox.Show("IO配置文件不存在");

            }
            else
            {
                VarAlarmList = new List<VarAlarm_Modbus>();
                XmlDocument xdoc = new XmlDocument();
                xdoc.Load(xmlpath);
                foreach (XmlNode nooderoot in xdoc.ChildNodes)
                {

                    if (nooderoot.Name == "Root")
                    {
                        foreach (XmlNode noodchild in nooderoot.ChildNodes)
                        {
                            if (noodchild.Name == "VariableAlarm")
                            {

                                VarAlarm_Modbus objVar = new VarAlarm_Modbus();
                                objVar.VarName = XMLAttributeGetValue(noodchild, "VarName");
                                objVar.VarAlarm = GetAlarm(XMLAttributeGetValue(noodchild, "Alarm"));


                                VarAlarmList.Add(objVar);
                            }


                        }

                    }

                }


            }
            return VarAlarmList;

        }

        #endregion


        #region  根据字符串解析成Alarm集合

        /// <summary>
        /// 根据字符串解析成Alarm集合
        /// </summary>
        /// <param name="Alarm"></param>
        /// <returns></returns>
        private List<Alarm> GetAlarm(string Alarm)
        {
            List<Alarm>AlarmList=null;
            if (Alarm.Length > 0)
            { 
            AlarmList = new List<Alarm>();
                string[]strArray= Alarm.Split('|');
                for(int i=0;i<strArray.Length-1;i++)
                {
                    string[] res = strArray[i].Split(';');
                    AlarmList.Add(new Alarm()
                    {
                        AlarmType = res[0],
                        AlarmVaule = float.Parse(res[1]),
                        Priority = int.Parse(res[2]),
                        Note = res[3]
                    });
                }
            
            
            }

            return AlarmList;
        }

        #endregion

        private void FrmIOVarConfig_Load(object sender, EventArgs e)
        {
            this.VarList = LoadXML(VarPath);

            this.VarAlarmList = LoadAlarmXML(VarAlarmPath);

            UpdateDGV();
        }

        //判断报警变量是新增还是修改，True为修改，false为新增
        private bool SelectVarAlarm(VarAlarm_Modbus AlarmVar, List<VarAlarm_Modbus> VarAlarmList)
        { 
        string str=string.Empty;
            bool Res=false;
            foreach (VarAlarm_Modbus item in VarAlarmList)
            {
                if (item.VarName == AlarmVar.VarName)
                {
                    Res = true;
                
                }
            }
        return Res;
        }


    }
}
